package world.criver.h50529.controller;

import javafx.application.Platform;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.util.Duration;
import world.criver.h50529.data.daControllers;
import world.criver.h50529.data.daData;
import world.criver.h50529.enums.enumKeyCode;
import world.criver.h50529.function.funFiles;
import world.criver.h50529.module.moEvent;
import world.criver.h50529.module.moListen;

import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;

public class conPage2Add implements Initializable {
    public TextField hotkey;
    public TextField name;
    public ComboBox<String> events;
    public VBox list;

    private boolean listen_start=false;
    private boolean is_update=false;

    public void ini(){
        is_update=false;
        list.getChildren().clear();
        name.setText("");
        name.setEditable(true);
        this.name.setPromptText("热键名称");
        this.name.setStyle("-fx-prompt-text-fill: #bbb");
        hotkey.setText("");
        this.hotkey.setPromptText("热键输入");
        this.hotkey.setStyle("-fx-prompt-text-fill: #bbb");
        iniEvents();
    }
    public void load(moListen mo){
        is_update=true;
        list.getChildren().clear();
        name.setEditable(false);
        name.setText(mo.getName());
        hotkey.setText(mo.getHotkey());
        for(int i=0;i<mo.getAwait_time().size();i++){
            addItem(mo.getEvents().get(i),""+mo.getAwait_time().get(i));
        }
        iniEvents();
    }
    private void iniEvents(){
        events.getItems().clear();
        for(moEvent mo: daData.events)events.getItems().add(mo.getName());
        if(!events.getItems().isEmpty())events.getSelectionModel().select(0);
    }

    public void onAddListen() {
        String name=this.name.getText();
        if(name.isEmpty()){
            this.name.setPromptText("名称不得为空");
            this.name.setStyle("-fx-prompt-text-fill: #f228");
            return;
        }
        String hotkey=this.hotkey.getText();
        if(hotkey.isEmpty()){
            this.hotkey.setPromptText("名称不得为空");
            this.hotkey.setStyle("-fx-prompt-text-fill: #f228");
            return;
        }
        if(list.getChildren().isEmpty())return;
        ArrayList<Double> awaits=new ArrayList<>();
        ArrayList<String> events=new ArrayList<>();
        for(int i=0;i<list.getChildren().size();i++){
            HBox h= (HBox) list.getChildren().get(i);
            String a=((TextField)h.getChildren().get(1)).getText();
            double s=0;
            if(a.contains("."))s=Double.parseDouble("0"+a+"0");
            else s=Double.parseDouble("0"+a);
            awaits.add(s);
            Label l=((Label)h.getChildren().get(2));
            events.add(l.getText().split(" ")[1]);
        }
        moListen listen=new moListen();
        listen.setName(name);
        listen.setHotkey(hotkey);
        listen.setForbidden(false);
        listen.setAwait_time(awaits);
        listen.setEvents(events);
        if(is_update){
            for(moListen m:daData.listens){
                if(!m.getName().equals(name)){
                    if(m.getHotkey().equals(hotkey)){
                        this.hotkey.setPromptText("已存在热键，请重新输入");
                        this.hotkey.setStyle("-fx-prompt-text-fill: #f118");
                        this.hotkey.setText("");
                        return;
                    }
                }
            }
            for(moListen m:daData.listens){
                if(m.getName().equals(name)){
                    daData.listens.remove(m);
                    break;
                }
            }
        }
        daData.listens.add(listen);
        new funFiles().saveListen(listen);
        daControllers.master.onMenuItem2();
    }

    public void onAddEvent() {
        String en=events.getSelectionModel().getSelectedItem();
        addItem(en,"");
    }
    private void addItem(String en,String delay){
        if(en.isEmpty())return;
        HBox hb=new HBox();
        hb.setId(System.currentTimeMillis()+"");
        hb.getStyleClass().add("HBox");
        Label l1=new Label("延时");
        hb.getChildren().add(l1);
        TextField t=new TextField(delay);
        t.setPromptText("0.00");
        t.setTextFormatter(new TextFormatter<String>(e->{
            String q=e.getControlNewText();
            if(q.matches("\\d*\\.?\\d*"))return e;
            else return null;
        }));
        hb.getChildren().add(t);
        Label l2=new Label("s，触发 "+en+" 事件");
        l2.setPrefWidth(620-46*2);
        hb.getChildren().add(l2);
        Button up=new Button("上移");
        up.setOnAction(e->{
            VBox vb= (VBox) hb.getParent();
            int num=0;
            for(int i=0;i<vb.getChildren().size();i++){
                if(((HBox)vb.getChildren().get(i)).getId().equals(hb.getId())){
                    num=i;
                    break;
                }
            }
            if(num<=0)return;
            vb.getChildren().remove(hb);
            vb.getChildren().add(num-1,hb);
        });
        hb.getChildren().add(up);
        Button down=new Button("下移");
        down.setOnAction(e->{
            VBox vb= (VBox) hb.getParent();
            int num=0;
            for(int i=0;i<vb.getChildren().size();i++){
                if(((HBox)vb.getChildren().get(i)).getId().equals(hb.getId())){
                    num=i;
                    break;
                }
            }
            if(num>=vb.getChildren().size()-1)return;
            vb.getChildren().remove(hb);
            vb.getChildren().add(num+1,hb);
        });
        hb.getChildren().add(down);
        Button bu=new Button("删除");
        bu.setOnAction(e->{
            list.getChildren().remove(hb);
        });
        hb.getChildren().add(bu);
        list.getChildren().add(hb);
        list.layout();
    }

    public void onStartSetHotkey() {
        listen_start=true;
        hotkey.setText("");
        Thread.startVirtualThread(() -> {
            int n=0;
            boolean add=true;
            while(listen_start && hotkey.isFocused()){
                int finalN = n;
                Platform.runLater(()->{
                    hotkey.setStyle("-fx-border-color: rgba(0,0,0,"+(0.03* finalN+0.07)+")");
                });
                try{Thread.sleep(100);}catch (Exception e){}
                if(add)n++;
                else n--;
                if(n>9)add=false;
                if(n<1)add=true;
            }
            hotkey.setStyle("-fx-border-color: rgba(0,0,0,0.07)");
            listen_start=false;
        });
    }

    public void onAddHotkey(KeyEvent e) {
        if(!listen_start)return;
        System.out.println(e.getCode().getName()+"="+e.getCode().getCode());
        String qw=hotkey.getText();
        String key=e.getCode().getName().replaceAll(" ","");
        boolean ok=false;
        for(enumKeyCode kc:enumKeyCode.values()){
            if(kc.name().equals("_"+key)){
                ok=true;
                break;
            }
        }
        if(!ok)return;
        if(qw.contains(key))return;
        qw+=(qw.isEmpty()?"":"+")+key;
        if(!isHotkeyCorrect(qw))return;//检测热键是否正确
        hotkey.setText(qw);
        if(!isHotkeyEnd(qw))return;//检测热键是否完成
        listen_start=false;
    }

    /**
     * 正确热键组合
     * 单个 > 非Ctrl、Windows、Alt、Shift、Fn、三
     * 两个 > Ctrl+? 或 Windows+? 或 Shift+?
     * 三个 > Ctrl+Alt+? 或 Ctrl+Shift+? 或 Windows+Shift+?
     * @param ks
     * @return
     */
    private boolean isHotkeyCorrect(String ks){
        String[] qw=ks.split("\\+");
        if(qw.length==0)return true;
        else if(qw.length==1){
            return !qw[0].equals("Alt");
        }else{
            if(qw[0].equals("Windows")){
                return !qw[1].equals("Alt");
            }
            if(qw.length==3){
                return !(qw[2].equals("Ctrl")||qw[2].equals("Windows")||qw[2].equals("Shift")||qw[2].equals("Alt"));
            }
        }
        return true;
    }

    /**
     * 检测热键是否完成
     * @param ks
     * @return
     */
    private boolean isHotkeyEnd(String ks){
        String[] qw=ks.split("\\+");
        if(qw.length==0)return false;
        else {
            int end=qw.length-1;
            return !(qw[end].equals("Ctrl") || qw[end].equals("Windows") || qw[end].equals("Shift") || qw[end].equals("Alt"));
        }
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        Platform.runLater(()->{
            name.setTextFormatter(new TextFormatter<String>(e->{
                String q=e.getControlNewText();
                return ((q.length()<=8 && q.matches("^[\\p{L}\\p{N}]+$"))||q.isEmpty())?e:null;
            }));
        });
    }
}
